# coding:utf-8
class Account < ActiveRecord::Base
  has_paper_trail :version => :paper_trail_version, :versions => :paper_trail_versions
  extend OpenSpreadsheet
  belongs_to :account_group, counter_cache: true
  attr_accessible :last_seen, :mobile_number, :account_group_id, :is_recommander,:name,:imported,:level, :password, :password_confirmation
  attr_accessor :level_before, :level_change, :level_after
  validates :mobile_number, uniqueness: true
  validates :mobile_number, format: /\A\d{11}\z/
  has_many :account_signins, :dependent => :destroy 
  belongs_to :register_terminal,class_name: "Terminal",foreign_key: :register_terminal_id

  #has_secure_password

  # Add skip password.Since 4.X versions of rails, has_secure_password takes an option :validations.
  # If you set it to false, it will not run validations. 
  attr_reader :password
  attr_accessor :not_skip_password

  validates_confirmation_of :password, :if => :not_skip_password
  validates_presence_of     :password_digest, :if => :not_skip_password

  include InstanceMethodsOnActivation

  if respond_to?(:attributes_protected_by_default)
    def self.attributes_protected_by_default
      super + ['password_digest']
    end
  end
  # Add skip password end

  # recommander relationship
  belongs_to :recommander, class_name: 'Account'
  has_many :recommands, foreign_key: 'recommander_id'

  scope :before_date, lambda {|date| where(["created_at < ?", 1.days.since(Time.zone.parse(date)).strftime("%Y-%m-%d")])}
  scope :after_date, lambda {|date| where(["created_at >= ?", date])}

  before_create :move_to_default_group, :driver_account_name_init
  after_save :init_is_recommander

  after_initialize :init
  def init
    self.is_recommander ||= false unless attributes["is_recommander"].nil?
  end

  # fix the counter cache in rails 3, rails4 has fix the counter_cache.
  # this is not a complete way .
  before_save :fix_counter_cache, :if => ->(er) { !er.new_record? && er.account_group_id_changed? }

  # account level

  def self.determine_level_change total, stay, promotion
    if total < stay
      -1
    else
      promotion > 0 ? (total - stay) / promotion : 0
    end          
  end

  def self.determine_level_after levels, level, level_change
    levels = levels.split(/\s*,\s*/).map(&:to_f)
    level = levels.index(level) || 0
    level_after = [[level + level_change, 0].max, levels.size - 1].min
    levels[level_after]
  end

  def to_s
    account_group ? "[#{account_group}]: #{mobile_number}" : "#{mobile_number}"
  end

  def self.total_counts_by(date_part)
    order_str = "max(EXTRACT(YEAR from accounts.created_at)) desc,max(DATE(accounts.created_at)) desc"
    case date_part
    when 'day'
      accounts = self.group("EXTRACT(YEAR from accounts.created_at),DATE(accounts.created_at)")
      accounts = accounts.order order_str
      accounts = accounts.select("EXTRACT(YEAR from accounts.created_at) as created_year,DATE(accounts.created_at) as created_part, count(accounts.id) as total")
    when 'week'
      accounts = self.group("EXTRACT(ISOYEAR from accounts.created_at),EXTRACT(#{date_part} from accounts.created_at)")
      accounts = accounts.order order_str
      accounts = accounts.select("EXTRACT(ISOYEAR from accounts.created_at) as created_year,EXTRACT(#{date_part} from accounts.created_at) as created_part, count(accounts.id) as total")
    when 'month','year'
      accounts = self.group("EXTRACT(YEAR from accounts.created_at),EXTRACT(#{date_part} from accounts.created_at)")
      accounts = accounts.order order_str
      accounts = accounts.select("EXTRACT(YEAR from accounts.created_at) as created_year,EXTRACT(#{date_part} from accounts.created_at) as created_part, count(accounts.id) as total")
    end
  end

  def phone_detail_info
    [self.province,self.city,self.card_type].join
  end

  def current_traffic
    traffics.sum(:flow,:conditions => ["created_at <= ? and created_at >= ?",Time.now.end_of_month,Time.now.beginning_of_month])
  end

  def seen
    self.last_seen = Time.now
  end

  def insert_detail_info
    response = Net::HTTP.get(URI("http://life.tenpay.com/cgi-bin/mobile/MobileQueryAttribution.cgi?chgmobile=#{self.mobile_number}"))
    #pp response.inspect
    if response.present?
      if response.match(/<retmsg>OK<\/retmsg>/)
        response = response.force_encoding("GBK").encode("UTF-8")
        response.match(/<city>(.+?)<\/city>/)
        self.city = $1.chop
        response.match(/<province>(.+?)<\/province>/)
        self.province = $1.chop
        response.match(/<supplier>(.+?)<\/supplier>/)
        self.card_type = $1.chop
      end
    end
  end

  def move_to_default_group
    unless self.account_group_id
      deag = AccountGroup.where(default: true).first
      self.account_group_id = deag.id if deag
    end
  end

  class << self
    def to_csv(options = {})
      CSV.generate(options) do |csv|
        csv << ["\xEF\xBB\xBF手机号","姓名"]
      end
    end

    def import(file,account_group_id)
      begin
        Account.transaction do
          file = open_spreadsheet(file)
          CSV.foreach(file.path, headers: true) do |row|
            row.to_hash.each do |key,value|
              account = Account.new(:account_group_id => account_group_id)
              value.split("\t").each_with_index do |attr_value,index|
                case index
                when 0
                  account.mobile_number = attr_value
                when 1
                  account.name = attr_value
                end
              end
              account.imported = true
              account.save!
            end
          end
        end
        true
      rescue => e 
        raise e
      end
    end
  end

  def display_imported
    !!self.imported ? '批量导入' : '注册用户'
  end

  private

  def init_is_recommander
    self.update_column(:is_recommander,self.account_group.is_recommander) if self.account_group
  end

  def fix_counter_cache
    if self.valid?
      AccountGroup.decrement_counter(:accounts_count, self.account_group_id_was)
      AccountGroup.increment_counter(:accounts_count, self.account_group_id)
    end
  end

  def driver_account_name_init
    tu = TerminalUser.where(["driver_phone = ? or driver_phone2 = ?",self.mobile_number,self.mobile_number]).first
    if tu
      if self.mobile_number == tu.driver_phone
        self.name = tu.driver_name
      elsif self.mobile_number == tu.driver_phone2
        self.name = tu.driver_name2
      end
    end
  end

end
